/*
 * File:   EntityManager.h
 * Author: RedEyedKiller
 *
 * Created on 24 Απρίλιος 2010, 12:28 πμ
 */

#ifndef _ENTITYMANAGER_H
#define	_ENTITYMANAGER_H


#include "Entity.h"
#include "EntityCreator.h"
#include "Factory.h"
#include "KeyMapper.h"
#include "Singleton.h"
#include "Vector2.h"
#include <list>

class KeyboardEvent;
class MouseEvent;

namespace EntitySystem
{

/**
 * A singleton class used to create and manage entities (game objects).
 * This class handles the creation, store, update and deletion of entities.
 */
class EntityManager
{
public:

    EntityManager();


    ~EntityManager();


    Entity* FindEntity(const std::string &ID);


    /**
     * Adds enity to state pool of entities.
     * @param entity - Entity to be added
     */

    void AddEntity(Entity* entity);


    /**
     * Creates a new Entity of subtype at x,y at the state entity pool.
     * @param subtype - The type of the entity. Most of the times is the name of xml file of the enity.(without the extension).
     * @param x - X position
     * @param y - Y position
     * @return The new Entity. Note that this entity is already added to entity pool.
     */

    Entity* RequestEntityImidAt(const std::string &subtype, int x, int y);


    /**
     * Creates a new Entity of subtype at x,y at the state entity pool.
     * @param subtype - The type of the entity. Most of the times is the name of xml file of the enity.(without the extension).
     * @param position - The position of the Entity
     * @return The new Entity. Note that this entity is already added to entity pool.
     */

    Entity* RequestEntityImidAt(const std::string &subtype, const Math::Vector2I& position);
    
    /**
     * Return true if a prototype for the specified entity has already been registered.
     * @param subtype
     * @return 
     */
    bool CheckPrototype(const std::string &subtype);

    /**
     * Registers given entity as a prototype to be used by entityCreator.
     * After this you can call RequestEntityImidAt(subType)
     * @param prototype
     * @param subtype
     * @return 
     */
    bool RegisterEntityPrototype(Entity* prototype,const std::string &subtype);
    
    /**
     * Calls the update method of all state Entities.
     * @param state - Target state.
     */

    void UpdateEntities();


    /**
     * removes all alive = false entities of the state
     */

    void BurryEntities();


    /**
     * Destroys all entities managed by the entity manager.
     */

    void DestroyAllEntities();


    /**
     * Informs all entities about a keyboard event.
     *
     * @param event: an occurred keyboard event.
     */

    void PushKeyboardInput(KeyboardEvent& event) const;


    /**
     * Informs all entities about a mouse event.
     * 
     * @param event: an occurred mouse event.
     */

    void PushMouseInput(MouseEvent& event) const;


private:
    std::list< Entity* > entityPool;

    EntityCreator* creator;
};

};

#endif	/* _ENTITYMANAGER_H */

